/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package Persistencia.JPAControllers;

import java.io.Serializable;
import javax.persistence.Query;
import javax.persistence.EntityNotFoundException;
import Logica.Core.Plantaciones.Plantacion;
import Logica.Core.MateriaPrima.YerbaPropia;
import Logica.Core.Plantaciones.Parcela;
import Persistencia.JPAControllers.exceptions.NonexistentEntityException;
import Persistencia.JPAControllers.exceptions.PreexistingEntityException;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

/**
 *
 * @author Luciano
 */
public class ParcelaJpaController implements Serializable {

    public ParcelaJpaController(EntityManagerFactory emf) {
        this.emf = emf;
    }
    private EntityManagerFactory emf = null;

    public ParcelaJpaController() {
        emf = Persistence.createEntityManagerFactory("SecaderoPU");

    }

    public EntityManager getEntityManager() {
        return emf.createEntityManager();
    }

    public void create(Parcela parcela) throws PreexistingEntityException, Exception {
        if (parcela.getMisYerbas() == null) {
            parcela.setMisYerbas(new ArrayList<YerbaPropia>());
        }
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            Plantacion miPlantacion = parcela.getMiPlantacion();
            if (miPlantacion != null) {
                miPlantacion = em.getReference(miPlantacion.getClass(), miPlantacion.getId());
                parcela.setMiPlantacion(miPlantacion);
            }
            List<YerbaPropia> attachedMisYerbas = new ArrayList<YerbaPropia>();
            for (YerbaPropia misYerbasYerbaPropiaToAttach : parcela.getMisYerbas()) {
                misYerbasYerbaPropiaToAttach = em.getReference(misYerbasYerbaPropiaToAttach.getClass(), misYerbasYerbaPropiaToAttach.getId());
                attachedMisYerbas.add(misYerbasYerbaPropiaToAttach);
            }
            parcela.setMisYerbas(attachedMisYerbas);
            em.persist(parcela);
            if (miPlantacion != null) {
                miPlantacion.getMisParcelas().add(parcela);
                miPlantacion = em.merge(miPlantacion);
            }
            for (YerbaPropia misYerbasYerbaPropia : parcela.getMisYerbas()) {
                Parcela oldMiParcelaOfMisYerbasYerbaPropia = misYerbasYerbaPropia.getMiParcela();
                misYerbasYerbaPropia.setMiParcela(parcela);
                misYerbasYerbaPropia = em.merge(misYerbasYerbaPropia);
                if (oldMiParcelaOfMisYerbasYerbaPropia != null) {
                    oldMiParcelaOfMisYerbasYerbaPropia.getMisYerbas().remove(misYerbasYerbaPropia);
                    oldMiParcelaOfMisYerbasYerbaPropia = em.merge(oldMiParcelaOfMisYerbasYerbaPropia);
                }
            }
            em.getTransaction().commit();
        } catch (Exception ex) {
            if (findParcela(parcela.getNro()) != null) {
                throw new PreexistingEntityException("Parcela " + parcela + " already exists.", ex);
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void edit(Parcela parcela) throws NonexistentEntityException, Exception {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            Parcela persistentParcela = em.find(Parcela.class, parcela.getNro());
            Plantacion miPlantacionOld = persistentParcela.getMiPlantacion();
            Plantacion miPlantacionNew = parcela.getMiPlantacion();
            List<YerbaPropia> misYerbasOld = persistentParcela.getMisYerbas();
            List<YerbaPropia> misYerbasNew = parcela.getMisYerbas();
            if (miPlantacionNew != null) {
                miPlantacionNew = em.getReference(miPlantacionNew.getClass(), miPlantacionNew.getId());
                parcela.setMiPlantacion(miPlantacionNew);
            }
            List<YerbaPropia> attachedMisYerbasNew = new ArrayList<YerbaPropia>();
            for (YerbaPropia misYerbasNewYerbaPropiaToAttach : misYerbasNew) {
                misYerbasNewYerbaPropiaToAttach = em.getReference(misYerbasNewYerbaPropiaToAttach.getClass(), misYerbasNewYerbaPropiaToAttach.getId());
                attachedMisYerbasNew.add(misYerbasNewYerbaPropiaToAttach);
            }
            misYerbasNew = attachedMisYerbasNew;
            parcela.setMisYerbas(misYerbasNew);
            parcela = em.merge(parcela);
            if (miPlantacionOld != null && !miPlantacionOld.equals(miPlantacionNew)) {
                miPlantacionOld.getMisParcelas().remove(parcela);
                miPlantacionOld = em.merge(miPlantacionOld);
            }
            if (miPlantacionNew != null && !miPlantacionNew.equals(miPlantacionOld)) {
                miPlantacionNew.getMisParcelas().add(parcela);
                miPlantacionNew = em.merge(miPlantacionNew);
            }
            for (YerbaPropia misYerbasOldYerbaPropia : misYerbasOld) {
                if (!misYerbasNew.contains(misYerbasOldYerbaPropia)) {
                    misYerbasOldYerbaPropia.setMiParcela(null);
                    misYerbasOldYerbaPropia = em.merge(misYerbasOldYerbaPropia);
                }
            }
            for (YerbaPropia misYerbasNewYerbaPropia : misYerbasNew) {
                if (!misYerbasOld.contains(misYerbasNewYerbaPropia)) {
                    Parcela oldMiParcelaOfMisYerbasNewYerbaPropia = misYerbasNewYerbaPropia.getMiParcela();
                    misYerbasNewYerbaPropia.setMiParcela(parcela);
                    misYerbasNewYerbaPropia = em.merge(misYerbasNewYerbaPropia);
                    if (oldMiParcelaOfMisYerbasNewYerbaPropia != null && !oldMiParcelaOfMisYerbasNewYerbaPropia.equals(parcela)) {
                        oldMiParcelaOfMisYerbasNewYerbaPropia.getMisYerbas().remove(misYerbasNewYerbaPropia);
                        oldMiParcelaOfMisYerbasNewYerbaPropia = em.merge(oldMiParcelaOfMisYerbasNewYerbaPropia);
                    }
                }
            }
            em.getTransaction().commit();
        } catch (Exception ex) {
            String msg = ex.getLocalizedMessage();
            if (msg == null || msg.length() == 0) {
                int id = parcela.getNro();
                if (findParcela(id) == null) {
                    throw new NonexistentEntityException("The parcela with id " + id + " no longer exists.");
                }
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void destroy(int id) throws NonexistentEntityException {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            Parcela parcela;
            try {
                parcela = em.getReference(Parcela.class, id);
                parcela.getNro();
            } catch (EntityNotFoundException enfe) {
                throw new NonexistentEntityException("The parcela with id " + id + " no longer exists.", enfe);
            }
            Plantacion miPlantacion = parcela.getMiPlantacion();
            if (miPlantacion != null) {
                miPlantacion.getMisParcelas().remove(parcela);
                miPlantacion = em.merge(miPlantacion);
            }
            List<YerbaPropia> misYerbas = parcela.getMisYerbas();
            for (YerbaPropia misYerbasYerbaPropia : misYerbas) {
                misYerbasYerbaPropia.setMiParcela(null);
                misYerbasYerbaPropia = em.merge(misYerbasYerbaPropia);
            }
            em.remove(parcela);
            em.getTransaction().commit();
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public List<Parcela> findParcelaEntities() {
        return findParcelaEntities(true, -1, -1);
    }

    public List<Parcela> findParcelaEntities(int maxResults, int firstResult) {
        return findParcelaEntities(false, maxResults, firstResult);
    }

    private List<Parcela> findParcelaEntities(boolean all, int maxResults, int firstResult) {
        EntityManager em = getEntityManager();
        try {
            Query q = em.createQuery("select object(o) from Parcela as o");
            if (!all) {
                q.setMaxResults(maxResults);
                q.setFirstResult(firstResult);
            }
            return q.getResultList();
        } finally {
            em.close();
        }
    }

    public Parcela findParcela(int id) {
        EntityManager em = getEntityManager();
        try {
            return em.find(Parcela.class, id);
        } finally {
            em.close();
        }
    }

    public int getParcelaCount() {
        EntityManager em = getEntityManager();
        try {
            Query q = em.createQuery("select count(o) from Parcela as o");
            return ((Long) q.getSingleResult()).intValue();
        } finally {
            em.close();
        }
    }
}
